package com.itheima.override;

public class Test {

    public static void main(String[] args) {
        Dog d = new Dog();
        d.cry();

        //方法重写的注意事项：
        //1.子类重写父类方法时，访问权限必须大于等于父类方法（public>protected>缺省）
        //2.重写的方法的返回值类型，必须和父类方法返回值类型一样，或者范围更小（例如Object>Integer）
        //3.私有方法和静态方法不能被重写

        /*
        在Java中，私有（private）方法不能被重写的主要原因是访问控制。(简单理解：子类继承的是父类的非私有成员）
        私有方法的访问修饰符限制了其可见性仅在声明它的类内部，这意味着其他类，甚至是子类，都无法访问到这个方法。
        因此，当一个方法被声明为私有时，子类就无法知道这个方法的存在，也就无从谈起重写它。

        重写（Overriding）发生在继承关系中，要求子类能够提供一个与父类相同签名的方法，
        但因为私有方法对子类不可见，所以这种机制无法应用于私有方法。
        如果你想在子类中改变一个方法的行为，你可以选择将方法声明为`protected`或者`public`，这样子类就能够访问并重写该方法。

        另外，如果一个方法被声明为`final`，无论其访问级别如何，都不能被重写，因为`final`关键字明确禁止了方法的重写行为。
         */

        /*
        在Java中，静态方法不能被重写的原因在于它们的查找和绑定机制。静态方法是与类本身关联，而不是与类的实例关联。这意味着当你调用一个静态方法时，Java虚拟机（JVM）会在编译时确定要调用的确切方法，这个过程称为静态绑定或早期绑定。

        当一个静态方法在一个类中被声明时，它直接属于那个类，而不属于任何特定的对象实例。因此，即使在子类中定义了一个具有相同签名的方法，这个方法也不会被认为是重写的，因为在运行时，静态方法的调用总是基于引用变量的静态类型，而不是实际对象的动态类型。
        换句话说，无论你使用什么类型的引用来调用静态方法，它总是会调用与引用类型相对应的那个类中的静态方法。

        因此，为了保证静态方法的正确调用和避免混淆，Java不允许在子类中重写父类的静态方法。如果你需要在子类中实现类似的功能，可以简单地在子类中定义一个新的静态方法，而无需使用重写的概念。
         */
    }

}

class Dog extends Animal{

    //方法重写：当子类觉得父类中的某个方法不好用，或者无法满足自己的需求时，
    //子类可以重写一个方法名称和参数列表都相同的方法，去覆盖父类的方法，
    //这称为方法重写。

    @Override      //方法重写的效验注解（标志），会检查方法名称和参数列表是否都相同，否则报错
    public void cry(){
        System.out.println("狗叫");
    }

    //实际开发中重写的规范：声明不变，重新实现（例public void cry()照抄，内容按需求写）
}

class Animal{
    public void cry(){
        System.out.println("动物叫");
    }
}
